package com.training.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.training.service.ProductService;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebServlet(name = "ProductController", urlPatterns = {"/api/products", "/api/products/*"})
public class ProductController extends HttpServlet {
    private final ProductService productService = new ProductService();
    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final int DEFAULT_PAGE_SIZE = 10;

    // GET - 获取产品列表或单个产品
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        try {
            String pathInfo = request.getPathInfo();
            
            if (pathInfo == null || pathInfo.equals("/")) {
                // 获取产品列表
                handleGetProductList(request, response);
            } else {
                // 获取单个产品
                handleGetSingleProduct(request, response, pathInfo);
            }
        } catch (Exception e) {
            handleError(response, e);
        }
    }

    // POST - 创建新产品
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        try {
            // 从请求体读取产品数据
            @SuppressWarnings("unchecked")
            Map<String, Object> productData = objectMapper.readValue(
                request.getReader(), 
                Map.class
            );

            // 验证必需字段
            if (!productData.containsKey("name") || !productData.containsKey("price") || !productData.containsKey("stock")) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing required fields: name, price, stock");
                return;
            }

            // 创建新产品
            Map<String, Object> newProduct = productService.createProduct(
                productData.get("name").toString(),
                Double.parseDouble(productData.get("price").toString()),
                Integer.parseInt(productData.get("stock").toString())
            );

            // 设置创建成功的状态码
            response.setStatus(HttpServletResponse.SC_CREATED);
            sendJsonResponse(response, newProduct);
        } catch (Exception e) {
            handleError(response, e);
        }
    }

    // DELETE - 删除产品
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        try {
            String pathInfo = request.getPathInfo();
            if (pathInfo == null || pathInfo.length() <= 1) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Product ID is required");
                return;
            }

            String productId = pathInfo.substring(1); // Remove the leading slash
            boolean deleted = productService.deleteProduct(Integer.parseInt(productId));
            
            if (!deleted) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Product not found");
                return;
            }

            // 返回删除成功的响应
            Map<String, String> result = new HashMap<>();
            result.put("message", "Product deleted successfully");
            sendJsonResponse(response, result);
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid product ID format");
        } catch (Exception e) {
            handleError(response, e);
        }
    }

    // PUT - 更新产品
    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        try {
            String pathInfo = request.getPathInfo();
            if (pathInfo == null || pathInfo.length() <= 1) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Product ID is required");
                return;
            }

            String productId = pathInfo.substring(1); // Remove the leading slash
            
            // 从请求体读取产品数据
            @SuppressWarnings("unchecked")
            Map<String, Object> productData = objectMapper.readValue(
                request.getReader(), 
                Map.class
            );

            // 验证必需字段
            if (!productData.containsKey("name") || !productData.containsKey("price") || !productData.containsKey("stock")) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing required fields: name, price, stock");
                return;
            }

            // 更新产品
            boolean updated = productService.updateProduct(
                Integer.parseInt(productId),
                productData.get("name").toString(),
                Double.parseDouble(productData.get("price").toString()),
                Integer.parseInt(productData.get("stock").toString())
            );
            
            if (!updated) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Product not found");
                return;
            }

            // 返回更新后的产品
            Map<String, Object> updatedProduct = productService.getProductById(Integer.parseInt(productId));
            sendJsonResponse(response, updatedProduct);
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid product ID or number format");
        } catch (Exception e) {
            handleError(response, e);
        }
    }

    // 处理获取产品列表的逻辑
    private void handleGetProductList(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        // 获取分页参数
        int page = getIntParameter(request.getParameter("page"), 1);
        int pageSize = getIntParameter(request.getParameter("size"), DEFAULT_PAGE_SIZE);
        String sortBy = request.getParameter("sortBy");
        String search = request.getParameter("search");

        // 获取分页后的商品列表
        List<Map<String, Object>> pageData = productService.getProductsWithPaginationAndSort(
            page, pageSize, sortBy, search
        );

        // 获取总数
        int totalItems = productService.getTotalCount(search);
        int totalPages = (int) Math.ceil((double) totalItems / pageSize);

        // 创建响应对象
        ObjectNode responseJson = objectMapper.createObjectNode();
        responseJson.put("totalItems", totalItems);
        responseJson.put("totalPages", totalPages);
        responseJson.put("currentPage", page);
        responseJson.putPOJO("items", pageData);

        sendJsonResponse(response, responseJson);
    }

    // 处理获取单个产品的逻辑
    private void handleGetSingleProduct(HttpServletRequest request, HttpServletResponse response, String pathInfo) 
            throws IOException {
        try {
            String productId = pathInfo.substring(1); // Remove the leading slash
            Map<String, Object> product = productService.getProductById(Integer.parseInt(productId));
            
            if (product == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "Product not found");
                return;
            }

            sendJsonResponse(response, product);
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid product ID format");
        }
    }

    // 工具方法
    private void handleError(HttpServletResponse response, Exception e) throws IOException {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        Map<String, String> error = new HashMap<>();
        error.put("error", "Internal Server Error");
        error.put("message", e.getMessage());
        response.getWriter().write(objectMapper.writeValueAsString(error));
    }

    private void sendJsonResponse(HttpServletResponse response, Object data) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(data));
    }

    private int getIntParameter(String value, int defaultValue) {
        if (value != null && value.matches("\\d+")) {
            return Integer.parseInt(value);
        }
        return defaultValue;
    }
}
